iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 30
4

前言
2020 秋天,我將用 30 天的時間,來嘗試回答和網路前端開發相關的 30 個問題。30 天無法一網打盡浩瀚的前端知識,有些問題可能對有些讀者來說相對簡單,不過期待這趟旅程,能幫助自己、也幫助讀者打開不同的知識大門。有興趣的話,跟著我一起探索吧!

來到鐵人賽的最後一天,應觀眾要求,今天來聊聊前端 framework。

如果在 Google 上搜尋 "frontend framework" 然後點入前幾個搜尋結果,可以看到當今熱門的前端 frameworks,像是

  • React.js
  • Angular.js
  • Vue.js
  • jQuery
  • Ember.js
  • ...

另外,還有常見的 frameworks 像是

  • Bootstrap
  • Sematic UI
  • Material UI
  • ...

這兩組都叫做 framework,但做的事情好像又不太一樣。到底什麼是 framework,前端為什麼需要 framework 呢?

What is a "framework"

In computer programming, a software framework is an abstraction in which software providing generic functionality can be selectively changed by additional user-written code, thus providing application-specific software. It provides a standard way to build and deploy applications and is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate development of software applications, products and solutions...

根據 Wiki 上的解釋:

  1. 「框架」是一種 "abstraction",提供了普遍性的功能,但開發者又能根據自己或產品的需求,選擇或調整當中的功能,以打造出獨特的應用程式。
  2. 「框架」提供了標準的方法,來讓開發者打造並部署應用程式。

那麼 "framework" 跟 "library" 有什麼差別呢?

Frameworks have key distinguishing features that separate them from normal libraries:

  1. inversion of control: In a framework, unlike in libraries or in standard user applications, the overall program's flow of control is not dictated by the caller, but by the framework.[1] This is usually achieved with the Template Method Pattern.
  2. default behaviour: This can be provided with the invariant methods of the Template Method Pattern in an abstract class which is provided by the framework.
  3. extensibility: A user can extend the framework – usually by selective overriding – or programmers can add specialized user code to provide specific functionality. This is usually achieved by a hook method in a subclass which overrides a template method in the superclass.
  4. non-modifiable framework code: The framework code, in general, is not supposed to be modified, while accepting user-implemented extensions. In other words, users can extend the framework, but cannot modify its code.

我想最大的差別在於,framework 不僅僅提供了功能性的支援,更規範出了規則與模式,也就是說,當使用了一個 framework 之後,就需要依照它所規定的範本來打造應用程式。當然使用時容許客製化,不過整體「架構」不會跑出該 framework 的規範。

所以舉例來說:

  • AJAX 不是 framework 也不是 library,它只是一種網站技術開發技術的集合 ( a set of web development techniques)
  • D3.js 是 library,提供資料視覺化的功能,但並沒有規範應用程式該如何打造
  • Mocha 是 framework,規範了測試的實作方式,同時也可以採用不同的 assertion library 像是 chai.js
  • jQuery 是 library,提供許多 DOM 操作的方法。

等等,剛剛上面不是看到 jQuery 是 framework 嗎?

如果在網路上走走,其實會發現並不是所有人都有相同精確的 framework 和 library 定義與區別,如果參考 Stack Overflow 或是 Quara 上面的討論,就會發現兩種說法都有人擁護。

當然在 jQuery 的官網 上,自己說自己是個 library(主角都自己說了,那其他人在吵什麼 XD)。不過我的看法是,早年 jQuery 推出之後,除了提供方面的操作功能之外,也改變了開發者在「特定範圍」內的開發方法與模式,因此有人會覺得 jQuery 會是個 framework。但今日的工具能力越來越強,管轄範圍也越來越大,大至整個應用程式的架構,也因此回頭看 jQuery 的時候就覺得它只是個 library。

我覺得爭論是 "framework" 或是 "library" 其實沒那麼重要,重要的是在開發的時候,需要知道這些工具的「角色」,不要使用的時候身在其中而不自知。

A little bit of history

我在鐵人賽的 第一篇文章 當中來了點歷史,在最後一天也再來一點吧。

HTML

1980 年代,歐洲核子研究中心 (CERN) 的科學家 Tim Berners-Lee 推出了 HTML 以及網際網路相關的協定,基本上形塑了當今網路的樣貌。我也在過去的許多文章當中提到了 Tim 的事蹟,這裡就不多說了。

最早期的網站非常簡單,當使用者向 server 送出請求之後,server 會送回靜態頁面 (HTML) 到使用者的瀏覽器,讓使用者能夠瀏覽資訊。這樣的靜態網站,其實沒有什麼方法可以和使用者互動,可能僅能夠透過 HTTP request 來更新頁面內容,或是送出資料 (form data)。

JavaScript

在 1993 年,Mosaic web browser 誕生,也是第一個擁有圖形化介面的瀏覽器,除了更適合非工程師的使用者使用,也刺激大家對於瀏覽器更多可能性的想像!

1994 年 Netscape Navigator 推出,短時間成為最多人使用的瀏覽器。不過,Netscape 也希望能夠為網站創造出更多的互動性,因此在 1995 年,Netscape 的工程師 Brendan Eich ,以神話般的 10 天創造出 JavaScript,為網站注入了生命力!

很快的,在 1996 年 Netscape 將 JavaScript 提交到 ECMA International 成為公開標準規範,讓世界上所有的瀏覽器都能夠依照相同的標準,來創造出網站與使用者的互動機制。

同一時間,Tim Berners-Lee 的同事 Håkon Wium Lie 在 1994 年提議了第一版的 CSS,並在 1996 年正式推出。

jQuery

有了 JavaScript 之後,各家瀏覽器就可以透過 DOM 來操作網站頁面,並可以與使用者互動。不過在發展初期,雖然各家都遵守 ECMA 的規範,但實作上可能還是有所差異;另一方面,在互動的設計越來越複雜的時候,程式碼也就越來越龐大和難以維護。

因此在 2006 年(一轉眼 10 年過去了)jQuery 誕生!jQuery 的核心功能在於讓開發者可以更簡單方便的操作、遍歷 DOM 元素。更重要的是,jQuery 幫助開發者可以跨越不同瀏覽器之間的差異。

另外,許多套件與 libraries 也因為 jQuery 而誕生,譬如早期的 Bootstrap,讓前端開發的領域開始加速發展,可以說是在 HTML, CSS, JavaScript 之後的重要發明之一!

AJAX

不過到目前為止,整個網路應用程式的架構都還是 SSR (server-sdie rendering)

如果以 server side 為 MVC 的架構為例


Source

MVC 分別代表 Model, View, Controller。當使用者透過瀏覽器發出 HTTP request 之後,server 當中的 controller 會解析並處理這個 request,並透過 model 來操作資料庫,像是提取資料或是更新資料。當 controller 拿到最新的資料之後,就會將資料和相對應得 view,送回給使用者,呈現出新的畫面。

也就是說,畫面的更新其實主要是由後端所驅動。

雖然之前的 JavaScript 或是 jQuery 能夠讓網站和使用者互動,但是如果某個互動需要讓畫面呈現「新的資料內容」,那麼就一定需要發出 HTTP request 到後端,才能讓整個畫面重新載入資料和渲染。

而如果在一個應用程式當中,使用者需要有大量資料操作的互動,那麼網站畫面更新的頻率就會很高,這樣在使用體驗或效率上都沒有很好。因此早在 1996 年,大家就在思考如何如何可以提高網站畫面更新的效率。

直到 2004 年,Google 在 Gmail 和 Google Map 兩個應用程式使用 Asynchronous JavaScript and XML 成果相當不錯,也吸引更多人對於 AJAX 設計的興趣。2005 年,AJAX 這個詞也正式的被大家所採用。

Frontend MVC

AJAX 的出現,讓前端能夠處理更多的互動、資料與畫面的呈現。這時候開發者又有更大膽的想法:那這樣是不是能夠直接在前端蓋 MVC 呢?

在過去,網站主要的畫面還是由後端,經過資料的更新後所提供,而 AJAX 只負責「部分」資料與畫面的更新。如果就讓前端完全負責使用者的互動與畫面更新(包含狀態管理),然後資料的存取僅透過 AJAX 和 API 來向 server 發出請求,這樣 server 就完全不需要在 HTTP response 當中的 body 夾帶任何畫面相關的檔案,是不是就能夠更有效率呢?

也因為要達到這個目的,前端需要有更多處理資料的能力,因此 Backbone.js 在 2010 年誕生,也讓網站進入了更豐富的 SPA (single-page application) 的時代,前端的角色也就越來越重要了!

(不過 SPA 的概念其實早在 2003 年就被提出)


Source

Angular, React, Vue

差不多在 Backbone.js 推出的同一時間 (2010),Google 大神推出了 Angular.js。

2013 年社群老大 Facebook 推出 React.js。

2016 年前 Google/Angular 工程師 Evan You 隻手遮天推出 Vue.js。


Source

Angular, React, Vue 就這樣成為今日前端框架的三大家。這裡就先不談三者之間的差異,先來說明三者共同在前端所採用的 MVVM 設計模式。


Source

MVVM 分別代表

  • Model
  • View
  • ViewModel

最初在 2010 年左右由 Microsoft 所提出,和 MVC 架構最大的差異是將原本 的 Controller 拆分為 View Controller 和 View Model。

View controller 負責處理來自使用者的互動,在 MVVM 當中被併入到 view 裡面。view model 則負責管理對應到的 view 的資料狀態。

在 MVVM 當中,viewview model 是雙向綁定,也就是說 view 當中的使用者操作,可以引發 view model 當中狀態的改變;另一方面,view model 當中資料狀態的改變,也會引發 view 的改變。

這樣其中之一的好處,是能夠達成「數據驅動」,只要資料狀態有變動,就會同步更新畫面,也可以確保畫面和資料的一致性。

So?

前端的發展從一開始單純的 HTML, CSS, JavaScript,三者各司其職,變成後面看起來複雜的各種框架,我想最大的原因是,為了追求更好的使用者體驗,開發者越來越依賴前端的功能,而當前端的角色從單純呈現頁面,變成要同時「呈現頁面」、「管理使用者互動」、「管理資料與狀態」,很難想像如果只靠 JavaScript, DOM 和 AJAX,可以怎麼「快速」做到今日開發者可以做到的成果。

也因此,使用 framework (這裡指 Angular, React, Vue) 的好處在於

  • 將資料、畫面呈現、邏輯分開處理,提升未來開發與管理效率
  • 承上,也間接產生了可以重複利用的 UI 組件,可以在不同頁面中出現,呈現不同的資料
  • 大幅提升開發速度
  • ...

缺點可能是,因為 frameworks 本身定義了許多規範,因此不見得像單純的 HTML, CSS, JavaScript 容易上手。另外要能夠順利 debug 的話,也需要對該 framework 本身有足夠的認識才行。

而在上面比較少提到的 CSS frameworks (e.g., bootstrap),則提供了許多設定好的 CSS 與 JavaScript 的設定,讓開發者可以快速將特定樣式與互動套用在自己的專案上,省去自己寫 CSS 或是 JavaScript 的時間。其他好處像是:

  • 提升開發速度
  • 提供一致性的 UI 設計樣板
  • 提供完善的 layout 設計
  • 解決部分跨瀏覽器的問題
  • ...

當然缺點就是,如果遇到需要高度客製化 CSS 的情況,使用 framework 就不見得會比較快。另外通常使用 framework 需要載入較多的程式碼,其中許多可能是專案用不到的程式碼,無形中增加網頁載入的負擔。

End

在最後一天挑戰 frontend framework 實在是件不討好的事情,範圍很大,也不好找到切入點(然後也容易引戰 XD)。不過我想是一個很好的機會,停下來看看 frontend development 的發展以及各種 frameworks 的由來。

雖然技術發展日新月異,但我認為舊的技術不代表就完全沒有價值去瞭解,如果能知道舊技術在歷史洪流當中所扮演的承先啟後的角色,那麼,我們可能可以更能夠掌握技術發展的脈絡與趨勢,以及做好遇到下一次變革的準備。

前端開發 30 個問題到今天暫時告一個段落,希望過程中有些主題有引發讀者的興趣。寫作的過程中我也是不斷的在學習,如果有任何想法或指教,都歡迎和我說一聲。

再次謝謝所有花時間閱讀我的文章的朋友們!

Ref


TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player

More about me

"Life is like riding a bicycle. To keep your balance, you must keep moving."


上一篇
Event loop, macrotask and microtask
下一篇
完賽!
系列文
前端開發 30 個問題31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

2
ckchuang
iT邦新手 4 級 ‧ 2020-10-13 23:06:24

太厲害了,我只能幫忙 debug 個錯字:不見得 單純。

這篇說明很 TD,研究得好深入,原本只是在回想前端面試都問些什麼問題,你竟然就接受挑戰了,佩服!恭喜團長完賽!

我要留言

立即登入留言